package com.sky.service.impl;

import com.github.pagehelper.PageHelper;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.PasswordEditDTO;
import com.sky.entity.Employee;
import com.sky.enumeration.OperationType;
import com.sky.exception.AccountLockedException;
import com.sky.exception.AccountNotFoundException;
import com.sky.exception.PasswordErrorException;
import com.sky.mapper.EmployeeMapper;
import com.sky.properties.JwtProperties;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    private static final Logger log = LoggerFactory.getLogger(EmployeeServiceImpl.class);
    @Autowired
    private EmployeeMapper employeeMapper;

    //搭配使用jwt取出id的方法
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 添加员工
     * @param employeeDTO   前端接收的数据
     */
    @Override
    public Result<String> addEmployee(EmployeeDTO employeeDTO, HttpServletRequest request) {
        //判断username是否存在，此处理方法被全局异常捕获替代
        //if(!ObjectUtils.isEmpty(employeeMapper.queryByUsername(employeeDTO.getUsername()))) return Result.error("用户名已存在！");

        //创建员工对象
        Employee employee = new Employee();
        //属性拷贝
        BeanUtils.copyProperties(employeeDTO, employee);
        //设置默认密码
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
        //设置默认状态
        employee.setStatus(StatusConstant.ENABLE);


        /**
         * 此方法为从JWT从取出当前登录的用户id，但在拦截器中已取出，为避免冗余，建议使用ThreadLocal
         */
        /*//获取token
        String token = request.getHeader(jwtProperties.getAdminTokenName());
        //获取密钥
        String secretKey = jwtProperties.getAdminSecretKey();
        //解密jwt
        Claims claims = JwtUtil.parseJWT(secretKey, token);
        Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
        employee.setCreateUser(Long.valueOf(empId));
        employee.setUpdateUser(Long.valueOf(empId));*/

        /**
         * 使用ThreadLocal线程池获取id，并设置
         *
         * 现已被切面技术替代填充
         */
        /*Long empId = BaseContext.getCurrentId();
        employee.setCreateUser(Long.valueOf(empId));
        employee.setUpdateUser(Long.valueOf(empId));
        //设置创建时间
        employee.setCreateTime(LocalDateTime.now());
        //设置更新时间
        employee.setUpdateTime(LocalDateTime.now());
        //设置创建人和更新人*/

        //添加入库
        employeeMapper.insert(employee);
        return Result.success();
    }

    /**
     * 员工登录
     *
     * @param employeeLoginDTO
     * @return
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {
        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        Employee employee = employeeMapper.getByUsername(username);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (employee == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(employee.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (employee.getStatus() == StatusConstant.DISABLE) {
            //账号被锁定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return employee;
    }

    /**
     * 查询员工
     * @param name  传入的姓名
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public Result<PageResult> queryEmployeeByPage(String name, Integer page, Integer pageSize) {
        //创建PageResult对象封装分页数据
        PageResult pageResult = new PageResult();
        //开启动态拼接分页
        PageHelper.startPage(page,pageSize);
        //查询数据
        List<Employee> employeeList = employeeMapper.queryByPage(name);
        //封装数据到PageResult中
        pageResult.setTotal(employeeList.size());
        pageResult.setRecords(employeeList);
        //返回
        return Result.success(pageResult);
    }

    /**
     * 修改员工状态
     * @param status
     * @param id
     * @return
     */
    @Override
    public Result<String> updateByStatus(Integer status, Integer id) {
        //创建Employee对象
        Employee employee = Employee.builder()
                .status(status)
                .id(Long.valueOf(id)).build();
        //调用mapper进行修改
        employeeMapper.update(employee);
        //返回结果
        return Result.success();
    }

    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    @Override
    public Result<Employee> queryById(Integer id) {
        Employee employee = employeeMapper.getById(id);
        return Result.success(employee);
    }

    /**
     * 员工信息修改
     * @param employeeDTO
     * @return
     */
    @Override
    public Result updateByEmployee(EmployeeDTO employeeDTO) {
        //创建Employee对象，进行属性拷贝
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);
        //获取当前用户id
        Long empId = BaseContext.getCurrentId();
        //调用方法进行修改
        employeeMapper.update(employee);
        //返回
        return Result.success();
    }

    /**
     * 员工密码修改
     * @param passwordEditDTO
     * @return
     */
    @AutoFill(value = OperationType.UPDATE)
    @Override
    public Result updateByPassword(PasswordEditDTO passwordEditDTO) {
        //查询旧密码是否正确
        String oldPassword = passwordEditDTO.getOldPassword();
        Long currentId = BaseContext.getCurrentId();
        log.info("id:{},password:{}",currentId,oldPassword);
        oldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        Employee employee = employeeMapper.getByIdPassword(currentId,oldPassword);
        //不正确则返回
        if(ObjectUtils.isEmpty(employee)) Result.error("旧密码错误");
        //正确则修改
        employee.setPassword(DigestUtils.md5DigestAsHex(passwordEditDTO.getNewPassword().getBytes()));
        employeeMapper.update(employee);
        return Result.success();
    }
}
